[4/4] buzz teams: group published personas into rosters - #5845
[4/4] buzz teams: group published personas into rosters#5845Maxwellimus wants to merge 2 commits into
Conversation
99a2f1f to
2fa2150
Compare
8b726c0 to
ccd1e37
Compare
6c4e387 to
6472616
Compare
wolfyy970
left a comment
There was a problem hiding this comment.
Reviewed at exact head 6472616bc. The --id adoption guard is right, and always publishing instructions: null / persona_ids: [] is the correct new-client wire.
Member resolution still has a silent wrong-seat. match_members tries a slugified d-tag before display name, so a Desktop snapshot member "Herring" binds to a CLI persona at d-tag herring even when a UUID persona with that display name also exists. The ambiguous-name error never runs. --from of a Desktop team export then publishes the wrong roster and reports success.
Exact d-tag should still win for --persona herring. After that, a unique display name or an ambiguity error should win over a slugified collision. The case to pin is both a herring slug and a UUID Herring in the index: match_members(["Herring"]) currently returns herring.
6472616 to
4ce7cf6
Compare
Completes the definition surface: `buzz teams create|list|get|delete` writes kind:30176 over the personas from [3/4], from flags or a Desktop `.team.json` export. Membership resolution is the load-bearing part. A team event stores persona d-tags, and Desktop publishes personas under their record id — usually a UUID — while its team export names members only by display name. Matching on the slugified name would therefore resolve nothing for every Desktop-exported roster. `--persona` accepts a d-tag, a slugified d-tag, or a unique display name, in that order; an ambiguous display name is an error rather than a guess, and a member with no published persona is refused rather than published as a seat that silently stays empty. A team id is used verbatim, never normalized. The relay enforces the slug grammar on persona d-tags but only a length bound on team ids, and Desktop writes raw UUIDs and ids like `builtin-team:welcome` — normalizing would address a different coordinate than the one Desktop published, making its teams unreachable. Since kind:30176 has no envelope validator on the relay, the CLI is the only guard against a blank or oversized id. `instructions` and `persona_ids` are always published. On the wire an absent field means "publisher predates always-publish, membership unknown, preserve local" — distinct from an explicit empty. A new client must never claim the former, or a write meant to clear a roster reads as "leave it alone" and one meant to leave it alone wipes it. The e2e suite gains the relay rule the delete path depends on: a tombstone older than its target head is accepted, deletes nothing, and still reports OK. Signed-off-by: Max Lampert <maxwell@squareup.com>
match_members tried the slugified handle before display names, so a Desktop snapshot member "Herring" bound to an unrelated CLI persona at d-tag `herring` even when the UUID persona with that display name existed — a silent wrong roster, and the ambiguous-name error never ran. Order is now exact d-tag, unique display name (ambiguity errors), then slugified d-tag. The slug fall-through keeps resolving handles that are prettied forms of a CLI slug with a different display name.
4ce7cf6 to
283ba92
Compare
|
🤖 Fixed in Pinned tests:
Exact d-tag still wins for |
Completes the definition surface:
buzz teams create|list|get|deletewriteskind:30176 over the personas from [3/4], from flags or a Desktop
.team.jsonexport.
Membership resolution
The load-bearing part. A team event stores persona d-tags, and Desktop publishes
personas under their record id — usually a UUID — while its team export names
members only by display name. Matching on the slugified name would therefore
resolve nothing for every Desktop-exported roster.
--personaaccepts a d-tag, a slugified d-tag, or a unique display name, inthat order. An ambiguous display name is an error rather than a guess, and a
member with no published persona is refused rather than published as a seat that
silently stays empty.
Team ids are used verbatim
The relay enforces the slug grammar on persona d-tags but only a length bound on
team ids, and Desktop writes raw UUIDs and ids like
builtin-team:welcome.Normalizing would address a different coordinate than the one Desktop published,
making its teams unreachable. Since kind:30176 has no envelope validator on the
relay, the CLI is the only guard against a blank or oversized id.
The one id
createdoes slugify is one it derives from--name, soteams get "Red team"misses thered-teamit just wrote. Reads stay verbatim —normalizing them is what would break Desktop's ids — so the not-found error names
the slug instead.
Always-publish for
instructionsandpersona_idsOn the wire an absent field means "publisher predates always-publish, membership
unknown, preserve local" — distinct from an explicit empty. A new client must
never claim the former, or a write meant to clear a roster reads as "leave it
alone" and one meant to leave it alone wipes it.
Test plan
just cicrates/buzz-test-client/tests/e2e_team.rsgainstest_tombstone_older_than_head_does_not_delete, pinning the relay rule thedelete path in [3/4] depends on.
crates/buzz-cli/TESTING.md§6.13.Deferred
which
resolve_createnow reports locally instead of letting the write failopaquely after every member has resolved. Instructions are executable
configuration reaching an ACP harness verbatim, so the invisible-character
rules personas get in [2/4] apply on the merits — but Desktop applies no text
rules to a team, and a CLI-only rule would refuse a roster Desktop exported
legitimately. That asymmetry is the thing [2/4] exists to prevent, so closing
this means adding the rule on the Desktop side first.